import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:sxw_bluetooth_provider/sxw_bluetooth_provider.dart';

/// 封装 TSPL 指令集
class TsplPrintHelper {
  final List<String> _commands = [];

  List<String> get commands => [..._commands, ''];

  void init({
    int width = 75,
    int height = 50,
    int gap = 2,
    int direction = 0,
  }) {
    setSize(width, height);
    setGap(gap, 0);
    setDirection(direction);
    clearBuffer();
  }

  void clearCommands() {
    _commands.clear();
  }

  /// 添加打印命令
  void addCommand(String command) {
    _commands.add(command);
  }

  /// 添加打印命令
  void addCommands(List<String> commands) {
    _commands.addAll(commands);
  }

  /// 设置打印纸的尺寸
  void setSize(int width, int height) {
    addCommand('SIZE $width mm, $height mm');
  }

  /// 设置间距
  void setGap(int m, int n) {
    addCommand('GAP $m mm, $n mm');
  }

  /// 设置打印速度
  void setSpeed(double speed) {
    final speedText = speed.toStringAsFixed(1);
    addCommand('SPEED $speedText');
  }

  /// 设置打印浓度
  void setDensity(int density) {
    assert(density >= 0 && density <= 15);
    addCommand('DENSITY $density');
  }

  /// 设置打印方向
  void setDirection(int direction) {
    assert(direction == 0 || direction == 1);
    addCommand('DIRECTION $direction');
  }

  /// 设置参考坐标原点
  void setReference(int x, int y) {
    addCommand('REFERENCE $x, $y');
  }

  /// 清除打印缓存
  void clearBuffer() {
    addCommand('CLS');
  }

  /// 进一张纸
  void formFeed() {
    addCommand('FORMFEED');
  }

  /// 设置第一张打印位置
  void home() {
    addCommand('HOME');
  }

  /// 打印缓冲区输出
  void print([int m = 1, int n = 1]) {
    addCommand('PRINT $m,$n');
  }

  /// 添加 [text] 到打印队列
  /// [x] 横坐标
  /// [y] 纵坐标
  /// [font] 字体，可选值：'1', '2', '3', '4', '5', '6', '7', '8'
  void addText(
    String text, {
    int x = 0,
    int y = 0,
    String font = 'TSS24.BF2',
    int rotation = 0,
    num xScale = 1,
    num yScale = 1,
  }) {
    _commands.add('TEXT $x,$y,"$font",$rotation,$xScale,$yScale,"$text"');
  }

  /// 画线，BAR指令
  void addLine({
    @required int x1,
    @required int y1,
    @required int x2,
    @required int y2,
  }) {
    final width = x2 - x1;
    final height = y2 - y1;
    final x = x1;
    final y = y1;
    _commands.add('BAR $x,$y,$width,$height');
  }

  /// BarCode
  ///
  /// [type] 的可选值：
  /// | name | value |
  /// | - | - |
  /// | 128 | Code 128 |
  /// | 128M | Code 128M |
  /// | 25 | Code 25 |
  /// | 25C | Code 25C |
  /// | 39 | Code 39 |
  /// | 39C | Code 39C |
  /// | 93 | Code 93 |
  /// | EAN8 | EAN-8 |
  /// | EAN13 | EAN-13 |
  /// | CODA | codabar |
  /// | UPCA | UPC-A |
  /// | UPCE | UPC-E |
  ///
  void addBarCode({
    @required int x,
    @required int y,
    @required String type,
    @required int height,
    @required int readable,
    @required String code,
  }) {
    _commands.add('BARCODE $x,$y,"$type",$height,$readable,2,2,"$code"');
  }

  /// 绘制矩形(边框)
  void addBox({
    @required int left,
    @required int top,
    @required int right,
    @required int bottom,
    @required int thickness,
  }) {
    _commands.add('BOX $left,$top,$right,$bottom,$thickness');
  }

  /// 输出二维码
  ///
  /// [x] 横坐标
  /// [y] 纵坐标
  /// [eccLevel] 的可选值： 'L', 'M', 'Q', 'H'
  /// [cellWidth] 的可选值： 1 ~ 10
  /// [rotation] 的可选值： 0, 90, 180, 270
  void addQrcode({
    @required int x,
    @required int y,
    String eccLevel = "M",
    int cellWidth = 6,
    String mode = "A",
    int rotation = 0,
    @required String text,
  }) {
    _commands.add('QRCODE $x,$y,$eccLevel,$cellWidth,$mode,$rotation,"$text"');
  }

  String get commandText {
    return commands.join('\n');
  }

  List<int> getBytes([Encoding encoding]) {
    encoding ??= gbk;
    final cmd = commands.join('\n');
    return encoding.encode(cmd);
  }

  /// 添加表格类型的数据
  void addTableData({
    @required Map<String, String> values,
    int fontSize = 1,
    int width = 72 * 8,
    int height = 50 * 8,
    int margin = 15,
    int tableOuterBorder = 3,
    int tableInnerBorder = 2,
  }) {
    final keys = values.keys.toList();

    final left = margin;
    final top = margin;
    final right = width - margin;
    final bottom = height - margin;

    // 表格的外框线
    addBox(
      left: left,
      top: top,
      right: right,
      bottom: bottom,
      thickness: tableOuterBorder,
    );

    // 表格的横线
    for (var i = 1; i < keys.length; i++) {
      final y = top + (height - margin * 2) / keys.length * i;
      addLine(
        x1: left,
        y1: y.toInt(),
        x2: right,
        y2: y.toInt() + tableInnerBorder,
      );
    }

    // 行高
    final lineHeight = (height - margin * 2) / values.length;

    for (var i = 0; i < keys.length; i++) {
      final x = left + 10;
      final y = top + lineHeight * i + (lineHeight - 8 * fontSize) / 2;
      final key = keys[i];
      final value = values[key];
      addText(
        '$key: $value',
        x: x,
        y: y.toInt(),
        xScale: fontSize,
        yScale: fontSize,
      );
    }
  }
}
